<?php
/**
 * Created by PhpStorm.
 * User: Frings
 * Date: 2016/9/7
 * Time: 10:55
 */

namespace app\models;


use app\librarys\Tools;

Class Voucher
{
    /**
     * 判断单证状态
     * @param $start_index
     * @param $end_index
     * @return array
     */
    public static function checkVoucher($isSystemAdmin, $start_index, $end_index)
    {
        //检查是否存在这些卡片
        //管理员检查单证号是否为未使用状态,机构检查未使用和未绑定状态，激活状态
        $sql = '';
        if ($isSystemAdmin) {
            $sql = 'SELECT * FROM t_voucher WHERE status = 0 AND id>=:start_Index AND ID<=:end_Index';
        } else {
            $sql = 'SELECT * FROM t_voucher WHERE (status = 1 OR status = 2 OR status = 6) AND id>=:start_Index AND ID<=:end_Index';
        }

        $cmd = \Yii::$app->db->createCommand($sql);
        $cmd->bindValue(':start_Index', $start_index);
        $cmd->bindValue(':end_Index', $end_index);
        $vouchers = $cmd->queryAll();

        $vcount = count($vouchers);
        if ($vcount != ((int)$end_index - (int)$start_index + 1)) {
            $m = '';
            if ($isSystemAdmin) {
                $m = '单证号不存在或者状态不为未使用，包括以下单证号：';
            } else {
                $m = '单证号不存在或者状态不为未绑定，包括以下单证号：';
            }
            $flag = false;
            $voucherId = '';
            for ($i = $start_index; $i <= $end_index; $i++) {
                $voucherId = $i;
                foreach ($vouchers as $v) {
                    if ($v['id'] == $i) {
                        $flag = true;
                        break;
                    }
                }
                if (!$flag) {
                    $m = $m . $voucherId . ',';
                }
                $flag = false;
            }

            return ['status' => 1, 'message' => substr($m, 0, strlen($m) - 1)];
        }
    }

    /**
     * 修改单证状态
     * @param $start_index
     * @param $end_index
     * @param $status 0-未使用，1-已绑定，2-已激活，3-已使用，4-失效，5-过期 ,6--发送给机构已绑定(同1)
     * @return bool
     */
    public static function updateVoucherStatus($start_index, $end_index, $status)
    {
        $sql = 'UPDATE t_voucher SET status = :status WHERE id >= :start_index AND id <= :end_index';
        $cmd = \Yii::$app->db->createCommand($sql);
        $cmd->bindValue(':start_index', $start_index);
        $cmd->bindValue(':end_index', $end_index);
        $cmd->bindValue(':status', $status);

        $result = $cmd->execute();
        return $result > 0;
    }

    /**
     * 根据单证id修改状态
     * @param $id
     * @param $status
     * @return bool
     */
    public static function updateVoucherStatusById($id, $status)
    {
        $sql = 'UPDATE t_voucher SET status = :status WHERE id = :id';
        $cmd = \Yii::$app->db->createCommand($sql);
        $cmd->bindValue(':id', $id);
        $cmd->bindValue(':status', $status);

        $result = $cmd->execute();
        return $result > 0;
    }

    /**
     * 根据单证号起始获取状态的数量列表
     * @param $start_index
     * @param $end_index
     * @return array
     */
    public static function getVoucherStatusCount($start_index, $end_index)
    {
        $sql = 'SELECT status,count(*) AS count FROM t_voucher WHERE id >= :start_index AND ID<= :end_index GROUP BY status';
        $cmd = \Yii::$app->db->createCommand($sql);
        $cmd->bindValue(':start_index', $start_index);
        $cmd->bindValue(':end_index', $end_index);
        $result = $cmd->queryAll();
        return $result;
    }

    /**
     * 根据状态获取列表中的数量
     * @param $items
     * @param $status
     * @return int
     */
    public static function getVoucherStatusCountByStatus($items, $status)
    {
        if (count($items)) {
            foreach ($items as $item) {
                if ($item['status'] == $status) {
                    return $item['count'];
                }
            }
        }
        return 0;
    }

    /**
     * 根据id获取单证
     * @param $id
     * @return array|false|null
     */
    public static function getVoucherById($id)
    {
        $sql = 'SELECT * FROM t_voucher WHERE id = :id';
        $cmd = \Yii::$app->db->createCommand($sql);
        $cmd->bindValue(':id', $id);

        $result = $cmd->queryOne();
        if ($result == false) {
            return null;
        }
        return $result;
    }

    /**
     * 根据单证id进行激活
     * @param $id
     * @return array
     */
    public static function activateVoucher($id)
    {
        $voucher = self::getVoucherById($id);
        if ($voucher == null) {
            return ['status' => 1, 'message' => '单证不存在'];
        }
        if (!($voucher['status'] == 0 || $voucher['status'] == 1 || $voucher['status'] == 6)) {
            return ['status' => 1, 'message' => '单证状态不为未使用或已绑定，不能激活'];
        }
        $result = self::updateVoucherStatusById($id, 2);
        if (!$result) {
            return ['status' => 1, 'message' => '服务器错误'];
        }
        return ['status' => 0, 'message' => '执行成功'];
    }


    /**
     * 根据单证id进行失效
     * @param $id
     * @return array
     */
    public static function invalidateVoucher($id)
    {
        $voucher = self::getVoucherById($id);
        if ($voucher == null) {
            return ['status' => 1, 'message' => '单证不存在'];
        }
        if (!($voucher['status'] == 0 || $voucher['status'] == 1 || $voucher['status'] == 2)) {
            return ['status' => 1, 'message' => '单证状态不为未使用、已绑定或已激活，不能激活'];
        }
        $result = self::updateVoucherStatusById($id, 4);
        if (!$result) {
            return ['status' => 1, 'message' => '服务器错误'];
        }
        return ['status' => 0, 'message' => '执行成功'];
    }


    /**
     * 根据单证号开始结束获取单证列表
     * @param $start_index
     * @param $end_index
     * @return array
     */
    public static function getVoucherByStartEndIndex($start_index, $end_index)
    {
        $sql = 'SELECT t1.*,t2.create_datetime,t3.name,t3.phone FROM t_voucher t1
                  LEFT JOIN t_card_voucher_record t2 ON t2.voucher_id = t1.voucher
                  LEFT JOIN t_user t3 on t3.id = t2.user_id
                WHERE t1.id>=:start_index AND t1.id <= :end_index';
        $cmd = \Yii::$app->db->createCommand($sql);
        $cmd->bindValue(':start_index', $start_index);
        $cmd->bindValue(':end_index', $end_index);

        $result = $cmd->queryAll();
        return $result;
    }

    /**
     * 验证单证号
     * @param $voucher
     * @param $token
     * @return array|false|null
     * @throws \Exception
     */
    public static function authVoucher($voucher, $token)
    {
        $voucherItem = Voucher::getVoucherById($voucher);
        if ($voucherItem == null) {
            throw  new \Exception('单证号无效!');
        }

        switch ($voucherItem['status']) {
            case 0:
                throw new \Exception('单证号未绑定!');
                break;
            case 1:
                throw  new \Exception('单证号未激活');
                break;
            case 2: //单证号已激活
                break;
            case 3: // 单证号已使用
                break;
            case 4:
                throw new \Exception('单证号已失效!');
                break;
            case 5:
                throw new \Exception('单证号已过期!');
                break;
            default:
                throw new \Exception('单证号状态异常!');
                break;
        }

        if ($voucherItem['token'] != $token) {
            throw  new \Exception('单证号验证失败!');
        }

        return $voucherItem;
    }

    /**
     * 获取单证号所关联的卡片
     * @param $voucher
     * @return array|false|null
     */
    public static function getCardByVoucher($voucher)
    {
        $cmd = \Yii::$app->db->createCommand('
                SELECT t2.* FROM t_voucher t0
                LEFT JOIN t_card_voucher t1 ON t1.voucher_id=t0.id
                LEFT JOIN t_card t2 ON t2.id=t1.card_id
                WHERE t0.id=:voucher
                order by create_datetime DESC limit 1');

        $cmd->bindValue(':voucher', $voucher);
        $result = $cmd->queryOne();
        if ($result == false) {
            return null;
        }
        return $result;
    }

    /**
     * 使用单证号
     * @param $voucherId
     * @param $userId
     * @return int
     * @throws \yii\db\Exception
     */
    public static function useVoucher($voucherId, $userId)
    {
        $status = 0;
        $transaction = \Yii::$app->db->beginTransaction();
        try {
            $cmd = \Yii::$app->db->createCommand('CALL p_use_voucher(:in_voucher_id, :in_user_id)');
            $cmd->bindValue(':in_voucher_id', $voucherId);
            $cmd->bindValue(':in_user_id', $userId);

            $cmd->execute();

            $transaction->commit();
        } catch (\Exception $e) {
            $transaction->rollBack();
            $status = 1;
        }

        return $status;
    }

    /**
     * 获取所有单证号数量
     * @return false|null|string
     */
    public static function getAllVoucherCount()
    {
        $cmd = \Yii::$app->db->createCommand('SELECT COUNT(1) FROM t_voucher');
        $count = $cmd->queryScalar();
        return $count;
    }

    /**
     * 获取最大单证号
     * @return false|null|string
     */
    public static function getMaxVoucher()
    {
        $cmd = \Yii::$app->db->createCommand('SELECT MAX(id) FROM t_voucher');
        $result = $cmd->queryScalar();
        return $result;
    }

    /**
     * 批量生成单证号
     * @param $startId
     * @param $count
     * @param int $isCard 是否名片
     * @return bool
     */
    public static function gen($startId, $count, $isCard = 1)
    {
        $transaction = \Yii::$app->db->beginTransaction();
        try {
            $endId = $startId + $count;
            for ($i = $startId; $i < $endId; $i++) {
                $token = rand(0, 99999999);
                $token = str_pad($token, 8, '0', STR_PAD_LEFT);
                $voucher = str_pad($i, 8, '0', STR_PAD_LEFT);

                $cmd = \Yii::$app->db->createCommand('insert into `t_voucher` ( id, `status`, `is_card`, `voucher`, `token`) values (:id,  0, :is_card, :id, :token);');
                $cmd->bindValue(':id', $voucher);
                $cmd->bindValue(':token', $token);
                $cmd->bindValue(':is_card', $isCard);
                $cmd->execute();
            }

            $transaction->commit();
        } catch (\Exception $ex) {
            $transaction->rollBack();
            return false;
        }

        return true;
    }
}